package graphics;

import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;

import base.Environment;
import base.Environment.Configurations;

import agents.Agent;
import agents.UAP;

public class BarGraph {
	
	//	Class main elements
	private Environment env;
	private ChartPanel cPanel;
	
	//	BarChart description elements	
	String[] legendLabels= { "Farmed Amount", "Target Quota"};	
	String[] xAxisLabels;
	String xAxisTitle = "Agents";
	String yAxisTitle = "Quota Values";
	String graphTitle = "Agent Evolution";
	double barStep;	

	//	Data for charts
	CategoryDataset dataSet;
	double[][] data;
	
	//	Animation speed
	int animSpeed;
	
	

	protected BarGraph(Environment env, int animSpeed){
		this.env = env;
		this.animSpeed = animSpeed;
		init(env.getActiveAgents());		
		
	}
	
	private final void init(List<Agent> agents) {
		data = new double[2][agents.size()];		
		
		xAxisLabels = new String[agents.size()];
		for(int i=0; i<agents.size(); i++)
			xAxisLabels[i] = "A"+agents.get(i).getID();
		
		cPanel = new ChartPanel(createCurrentChart());
		barStep = env.getDouble(Configurations.QUOTA);
		
	}
	
	
	protected void animate(){
		int maxQuota = 0;
		int[] farms, targets;
		List<Agent> agents = env.getActiveAgents();	
		
		farms = new int[agents.size()];
		targets = new int[agents.size()];
		
		for(int i=0; i<agents.size(); i++){
			UAP agUAP = agents.get(i).getUAP();
			farms[i] = (int) agUAP.amount;
			targets[i] = agents.get(i).getQuota();			
			if (targets[i]>maxQuota)
				maxQuota = targets[i];
		}
		
		boolean animated = true;		
		while (animated){			
			animated = false;
			for(int i=0; i<agents.size(); i++){
				if (data[0][i]!=farms[i] || data[1][i] !=targets[i])
					animated = true;
				
				//	Adjust farm bar;
				if (data[0][i] < farms[i])
				{
					data[0][i] = (data[0][i]+barStep < farms[i]?data[0][i]+barStep:farms[i]);
				} else
					if (data[0][i] > farms[i]){
						data[0][i] = (data[0][i]-barStep > farms[i]?data[0][i]-barStep:farms[i]);
					}

				//	Adjust target bar;
				if (data[1][i] < targets[i])
				{
					data[1][i] = (data[1][i]+barStep < targets[i]?data[1][i]+barStep:targets[i]);
				} else
					if (data[1][i] > targets[i]){
						data[1][i] = (data[1][i]-barStep > targets[i]?data[1][i]-barStep:targets[i]);
					}
			}
			buildFrameChart();
			try {
				Thread.sleep(animSpeed);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		// Retrieve amount by which to increase the size of a bar; the step for the chart
		barStep = maxQuota / 20;
		
	}
	
	
	
	//	Creates initial panel for frame
	protected ChartPanel createInitialChartPanel(){
		return cPanel;
	}
	
	protected void setAnimationSpeed(int animSpeed){
		this.animSpeed = animSpeed;		
	}
	
	
	private void buildFrameChart(){
		cPanel.setChart(createCurrentChart());
	}
	
	/**
	 * Creates chart using current values in data[][]
	 * @return resulting JFreeChart
	 */
	private JFreeChart createCurrentChart(){
		JFreeChart result = null;
		CategoryDataset dataSet = DatasetUtilities.createCategoryDataset(legendLabels, 
				   xAxisLabels, data);
		result = ChartFactory.createBarChart(
				  graphTitle, xAxisTitle, yAxisTitle, dataSet,
				  PlotOrientation.VERTICAL, true, true, false);

		
		return result;
	}
	
	//	Test stuff
	protected void testAnimate(){
		System.out.println("animating");	
		for(int i=3; i<200; i++){
			System.out.println("nada");
			createTestData(i, i+i%10);
			cPanel.setChart(createCurrentChart());
			try {
				Thread.sleep(animSpeed);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	private void createTestData(double a, double b){
		data = new double[2][env.getActiveAgents().size()];
		for(int i=0; i<env.getActiveAgents().size(); i++){
			data[0][i] = a;
			data[1][i] = b;
		}
		//System.out.println("agents doing stuff " + env.getActiveAgents().size());
	}	


}
